package com.lyEducation.repositoryImpl.system;

import com.lyEducation.controllers.dto.system.userDetails.UserDetailsImpl;
import com.lyEducation.core.base.SysConstants;
import com.lyEducation.core.base.TreeEntityService.UpDownTreeEntityService;
import com.lyEducation.core.base.TreeEntityService.UpDownTreeEntityServiceImpl;
import com.lyEducation.entities.middle.SysRoleMenuEntity;
import com.lyEducation.entities.middle.SysRoleUserEntity;
import com.lyEducation.entities.middle.SysRoleUserEntityPK;
import com.lyEducation.entities.system.SysMenuEntity;
import com.lyEducation.entities.system.SysRoleEntity;
import com.lyEducation.entities.system.SysUserEntity;
import com.lyEducation.repository.redis.RedisRepository;
import com.lyEducation.repository.system.SysMenuRepository;
import com.lyEducation.repository.system.SysRoleRepository;
import com.lyEducation.repository.system.SysUserRepository;
import com.lyEducation.repositoryImpl.base.BaseCodeRepositoryImpl;
import com.lyEducation.security.config.SecurityPrincipalContext;
import com.lyEducation.util.EntityUtil;
import com.lyEducation.util.IpUtil;
import com.lyEducation.util.MD5Util;
import com.lyEducation.util.StringUtils;
import com.lyEducation.util.controllerUtil.JsonConstans;
import com.lyEducation.util.controllerUtil.JsonResult;
import com.lyEducation.util.jwt.JwtUtil;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Repository;

import javax.servlet.http.HttpServletRequest;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.*;

@Repository
public class SysUserRepositoryImpl extends BaseCodeRepositoryImpl<SysUserEntity>
    implements SysUserRepository {

  //  public static final String PASSWORD = "password";

  @Autowired private RedisRepository redisRepository;
  @Autowired private SysRoleRepository sysRoleRepository;
  @Autowired private SysMenuRepository sysMenuRepository;
  @Autowired private JwtUtil jwtUtil;

  //  public static void main(String args[]) {
  //    Map<Integer, List> map = new TreeMap<>();
  //    List list = new ArrayList();
  //    list.add(1);
  //
  //    map.put(2, list);
  //    map.put(3, list);
  //    map.put(1, list);
  //
  //    for (Map.Entry e : map.entrySet()) {
  //      LoggerFactory.getLogger(SysUserServiceImpl.class).info(e.getKey() + "--" + e.getValue());
  //    }
  //
  //    //    list = new ArrayList();
  //    list.add(2);
  //    list.add(66666);
  //    for (Map.Entry<Integer, List> e : map.entrySet()) {
  //      LoggerFactory.getLogger(SysUserServiceImpl.class)
  //          .info(e.getKey() + "--" + e.getValue().get(1));
  //    }
  //  }

  @Override
  public JsonResult doSaveOrUpdate(Map paramsMap) {
    try {
      String id = StringUtils.getMapKeyValue(paramsMap, "id");
      String code = StringUtils.getMapKeyValue(paramsMap, "code");
      boolean isExistCode = isExistCode(code, id);
      if (isExistCode) {
        return JsonResult.putFail(JsonConstans.ERR_CODE_EXISTS);
      }
      SysUserEntity sysUserEntity = null;
      if (StringUtils.isNotBlank(id)) {
        if (paramsMap.containsKey(SysConstants.PASSWORD)) {
          paramsMap.remove(SysConstants.PASSWORD);
        }
        sysUserEntity = findById(SysUserEntity.class, id);
        if (sysUserEntity == null) {
          return JsonResult.putFail(JsonConstans.ERR_NOT_EXISTED);
        }
        EntityUtil.putMapDataIntoEntity(paramsMap, sysUserEntity);
        update(sysUserEntity);
      } else {
        sysUserEntity = new SysUserEntity();
        EntityUtil.putMapDataIntoEntity(paramsMap, sysUserEntity);
        sysUserEntity.setPassword(MD5Util.encodeMD5(sysUserEntity.getPassword()));
        sysUserEntity.setIsDelete(Boolean.FALSE);
        save(sysUserEntity);
      }
      return JsonResult.putSuccess();
    } catch (Exception e) {
      e.printStackTrace();
      return JsonResult.putFail(JsonConstans.OPERATION_FAILURE);
    }
  }

  @Override
  public SysUserEntity getUserByCodeEmailMobile(String getUserByWhitchType, String var) {
      if (StringUtils.isBlank(var)) {
      return null;
    }
      String sql =
              "SELECT u.* FROM sys_user u WHERE u."
                      + getUserByWhitchType
                      + " =:"
                      + getUserByWhitchType
                      + " AND u.isDelete =0";
    Map<String, Object> conditionParams = new HashMap<>(1);
      conditionParams.put(getUserByWhitchType, var);
    List<SysUserEntity> userList =
        findByNativeQuery(sql, conditionParams, Transformers.aliasToBean(SysUserEntity.class));

    if (userList.size() > 1) {
      throw new RuntimeException("login user has " + (userList.size()));
    }
    if (userList.size() != 0) {
      return userList.get(0);
    }
    return null;
  }

    //  @Override
  //  public JsonResult doLogin(Map paramsMap) {
  //    String usercode = StringUtils.getMapKeyValue(paramsMap, "usercode");
  //    String password = StringUtils.getMapKeyValue(paramsMap, "password");
  //    if (StringUtils.isBlank(usercode) || StringUtils.isBlank(password)) {
  //      return JsonResult.putFail(JsonConstans.ERR_WRONG_PARAM);
  //    } else {
  //      SysUserEntity user = this.getUserMapByCode(usercode);
  //      if (user != null) {
  //        String userPassword = user.getPassword();
  //        password = MD5Util.encodeMD5(password);
  //        if (userPassword.equals(password)) {
  //          SysUserEntity sysUserEntity =
  //                  this.findById(SysUserEntity.class, user.getId().toString());
  ////          sysUserEntity.setUserToken(TokenConstants.generateToken());
  //          this.update(sysUserEntity);
  ////          redisRepository.delSession(user.get.toString());
  ////          userMap.put("userToken", sysUserEntity.getUserToken());
  //          userMap.remove("password");
  //          redisRepository.setSession(userMap);
  //          return JsonResult.putSuccess(userMap);
  //        } else {
  //          return JsonResult.putFail(JsonConstans.ERR_USER_PASSORD_NOTEQUAL);
  //        }
  //      } else {
  //        return JsonResult.putFail(JsonConstans.ERR_USER_PASSORD_NOTEQUAL);
  //      }
  //    }
  //  }

  @Override
  public boolean layout(HttpServletRequest request) {
    boolean isLayout = false;
    String userAccessToken = request.getHeader(SysConstants.USER_ACCESS_TOKEN.getValue());
    if (StringUtils.isNotBlank(userAccessToken)) {
      isLayout = redisRepository.delSession(userAccessToken);
    }
    return isLayout;
  }

  @Override
  public JsonResult addUserRole(Map paramsMap) {

    String roleIds = StringUtils.getMapKeyValue(paramsMap, "roleIds");
    String userId = StringUtils.getMapKeyValue(paramsMap, "userId");
    if (StringUtils.isBlank(userId) || StringUtils.isBlank(roleIds)) {
      return JsonResult.putFail(JsonConstans.ERR_WRONG_PARAM);
    }
    for (String roleId : roleIds.split(",")) {
      SysRoleUserEntityPK sysRoleUserEntityPK = new SysRoleUserEntityPK();
      sysRoleUserEntityPK.setRoleId(roleId);
      sysRoleUserEntityPK.setUserId(userId);
      SysRoleUserEntity sysRoleUserEntity =
          findByIdClass(new SysRoleUserEntity(), sysRoleUserEntityPK);
      if (sysRoleUserEntity == null) {
        sysRoleUserEntity = new SysRoleUserEntity();
        sysRoleUserEntity.setRoleId(roleId);
        sysRoleUserEntity.setUserId(userId);
        sysRoleUserEntity.setCreateTime(new Timestamp(System.currentTimeMillis()));
        save(sysRoleUserEntity);
      }
    }
    //    sysRoleUserRepository.deleteByRoleUserId(userId, roleIds);
    return JsonResult.putSuccess();
  }


    @Override
  public void updUserParamByLoginSuccess(HttpServletRequest httpServletRequest)
      throws UnknownHostException {
    //    loginSuccessOutParamSet(true, httpServletRequest);
        LinkedHashMap<String, Object> valueParams = new LinkedHashMap();
        Map conditionParams = new HashMap<String, String>();
    UserDetailsImpl userDetailsImpl =
        (UserDetailsImpl) SecurityPrincipalContext.getUserDetailsImpl();
    Timestamp nowTime = new Timestamp(System.currentTimeMillis());
        String updateTime = "updateTime";
        String updateId = "updateId";
        String loginIp = "loginIp";
        String id = "id";
        valueParams.put(updateTime, nowTime);
        valueParams.put(updateId, userDetailsImpl.getId());
        valueParams.put(loginIp, IpUtil.getIpAddrByNginx(httpServletRequest));
        conditionParams.put("id", userDetailsImpl.getId());
        StringBuffer sb = new StringBuffer();
        sb.append("AS u set u.").append(updateTime).append("=:").append(updateTime).append(",u.").append(updateId).append("=:").append(updateId).append(",u.").append(loginIp).append("=:").append(loginIp).append(" where u.").append(id).append("=:").append(id);
        this.updateFileds(sb.toString(), conditionParams, valueParams);
  }

  //  @Override
  //  public void updUserParamByLoginOut(HttpServletRequest httpServletRequest)
  //      throws UnknownHostException {
  //    loginSuccessOutParamSet(false, httpServletRequest);
  //  }

  //  private void loginSuccessOutParamSet(
  //      boolean loginSuccessOut, HttpServletRequest httpServletRequest) throws
  // UnknownHostException {
  //    LinkedHashMap<String, Object> paramMap = new LinkedHashMap();
  //    SystemUserDto systemUserDto = SysUserUtils.getSystemUserDto();
  //    Timestamp nowTime = new Timestamp(System.currentTimeMillis());
  //    paramMap.put("loginTime", nowTime.toString());
  //    if (loginSuccessOut) {
  //      paramMap.put("updateTime", nowTime.toString());
  //    } else {
  //      paramMap.put("loginOutTime", nowTime.toString());
  //    }
  //    paramMap.put("updateId", systemUserDto.getId());
  //    paramMap.put("loginIp", IpUtil.getIpAddrByNginx(httpServletRequest));
  //    paramMap.put("id", systemUserDto.getId());
  //    this.updateFileds(paramMap);
  //  }

  //  /**
  //   * 如果jwtToken存在且不过期这里不应该执行查询账号操作而是根据token生成账户，修改账户操作就必须查询最新数据
  //   *
  //   * @param s username
  //   * @return
  //   * @throws UsernameNotFoundException
  //   */
  //  @Override
  //  public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
  //    String[] usernameJwtToken = s.split(",");
  //    Map<String, Object> jwtTokenMap = null;
  //    if (usernameJwtToken.length > 1) {
  //      try {
  //        jwtTokenMap = jwtUtil.validateToken(usernameJwtToken[0]);
  //      } catch (Exception e) {
  //        return getSysUserEntityByCode(usernameJwtToken[1]);
  //      }
  //      if (jwtTokenMap != null) {
  //        return SystemUserDto.createUserDetailByMap(jwtTokenMap);
  //      }
  //    }
  //    return getSysUserEntityByCode(s).createSystemUserDto();
  //  }

    @Override
    public SysUserEntity setLoginUserRoleMenu(SysUserEntity user) {
        // 查询用户权限,多个权限能同级但不能上下级
        Map<String, Object> paramMap = new HashMap();
        paramMap.put("userId", user.getId());
        String sql = "SELECT ru.* from sys_role_user ru where ru.userId=:userId";
        List<SysRoleUserEntity> resRoleUser =
                findByNativeQuery(sql, paramMap, Transformers.aliasToBean(SysRoleUserEntity.class));
        if (resRoleUser != null && resRoleUser.size() > 0) {
            paramMap.clear();
            List<String> paramList = new ArrayList();
            for (SysRoleUserEntity roleUser : resRoleUser) {
                paramList.add(roleUser.getRoleId());
            }
            paramMap.put("roleIdList", paramList);
            //      sql = "SELECT r.id,r.name from sys_role r where r.id in (:roleIdList)";
            List<SysRoleEntity> resRoleList = sysRoleRepository.findRolesByRoleIdList(paramMap);
            //      查询该用户所有权限所有菜单
            if (resRoleList != null && resRoleList.size() > 0) {
                user.setRoles(resRoleList);
                sql = "SELECT * from sys_role_menu where roleId in(:roleIdList)";
                //                用户多个权限下权限不为上下级关系只能同级,或不同级等级差，
                // 只需要拿到最高级别权限的权限菜单中间表记录，如果最高级别权限有多个，则需要同时都获取到
                List<SysRoleMenuEntity> roleMenuList =
                        findByNativeQuery(sql, paramMap, Transformers.aliasToBean(SysRoleMenuEntity.class));
                if (roleMenuList != null && roleMenuList.size() > 0) {
                    paramMap.clear();
                    paramList.clear();
                    for (SysRoleMenuEntity roleMenu : roleMenuList) {
                        paramList.add(roleMenu.getMenuId());
                    }
                    paramMap.put("menuIdList", paramList);
                    //          sql = "SELECT * from sys_menu where id in(:menuIdList)";
                    //          List<SysMenuEntity> resMenuList =
                    //              findByNativeQuery(sql, paramMap,
                    // Transformers.aliasToBean(SysMenuEntity.class));
                    List<SysMenuEntity> resMenuList = sysMenuRepository.findMenusByMenuIdList(paramMap);
                    if (resMenuList != null && resMenuList.size() > 0) {
                        //            将菜单menu归类到对应用户权限下
                        resMenuList:
                        for (SysMenuEntity menuEntity : resMenuList) {
                            for (SysRoleMenuEntity sysRoleMenuEntity : roleMenuList) {
                                if (menuEntity.getId().equals(sysRoleMenuEntity.getMenuId())) {
                                    for (SysRoleEntity roleEntity : resRoleList) {
                                        if (roleEntity.getId().equals(sysRoleMenuEntity.getRoleId())) {
                                            TreeSet<SysMenuEntity> menuSet = roleEntity.getMenus();
                                            if (menuSet == null) {
                                                roleEntity.setMenus(null);
                                                menuSet = roleEntity.getMenus();
                                            }
                                            menuSet.add(menuEntity);
                                            continue resMenuList;
                                        }
                                    }
                                }
                            }
                        }
                        // 将菜单menu累计上下级

                        //            登陆菜单
                        UpDownTreeEntityService<SysMenuEntity> upDownTreeEntityService =
                                UpDownTreeEntityServiceImpl.createUpDownTreeEntityService(SysMenuEntity.class);
                        user.setMenus(upDownTreeEntityService.upDownTreeEntity(resMenuList));
                    }
                    //    需要更新登录成功后的参数信息无法传request获取ip，
                    // 在sysUserRepository.update()无法获取当前线程的登陆者对象SysUserEntity u =
                    // SysUserUtils.getCurrentSysUser();还没set进去，
                    // system.currentTimeMillis()));
                    //    在AuthenticationSuccessHandlerImpl登录成功处理类可以解决这些问题
                    //    sysUserRepository.update(user);
                }
            }
        }
        return user;
    }

  @Override
  public Set<SysRoleEntity> userGetMaxLevelSysRoleSet() {
    return SysUserEntity.getMaxLevelSysRoleSet(userGetRoleList(null, null));
  }

  @Override
  public List<SysRoleEntity> userGetRoleList(
      Map<String, Object> paramMap, List<String> roleNameList) {
    if (paramMap == null) {
      paramMap = new HashMap<>();
    }
    if (roleNameList == null) {
      roleNameList = new ArrayList();
    }
    paramMap.put("roleNameList", roleNameList);
    for (GrantedAuthority grantedAuthority :
        SecurityPrincipalContext.getUserDetails().getAuthorities()) {
      roleNameList.add(grantedAuthority.getAuthority());
    }
    return sysRoleRepository.findRolesByRoleNameList(paramMap);
  }

  //  @Override
  //  public TreeSet<SysMenuEntity> upDownMenu(List<SysMenuEntity> sysMenuEntityList) {
  //
  //    if (sysMenuEntityList.size() > 1) {
  //      HashSet<SysMenuEntity> vertexMenuSet = new HashSet<SysMenuEntity>();
  //      //      还是要考虑多个顶级菜单
  //      //      菜单集合剩余都是顶点菜单集则排序结束
  //
  //      while (!vertexMenuSet.containsAll(sysMenuEntityList)) {
  //        SysMenuEntity menuEntity = null;
  //        for (int i = 0; i < sysMenuEntityList.size(); i++) {
  //          menuEntity = sysMenuEntityList.get(i);
  //          if (!vertexMenuSet.contains(menuEntity)) {
  //            break;
  //          }
  //        }
  //
  //        //        SysMenuEntity levelMenu = allReadySortMenuSet.first();
  //        //        if (levelMenu == null) {
  //        //          allReadySortMenuSet.add(menuEntity);
  //        //        } else {
  //        //          if (menuEntity.getLevel() < levelMenu.getLevel()) {
  //        //            allReadySortMenuSet.clear();
  //        //            allReadySortMenuSet.add(menuEntity);
  //        //          } else if (menuEntity.getLevel() == levelMenu.getLevel()) {
  //        //            allReadySortMenuSet.add(menuEntity);
  //        //          }
  //        //        }
  //
  //        //        顶点菜单赋予其所有下级菜单并从菜单集合去除其所有下级菜单
  //        setChilendMenu(menuEntity, sysMenuEntityList);
  //        //     首选顶点菜单可能会存在上级需要重新加回来
  //        sysMenuEntityList.add(menuEntity);
  //        //        每个作为顶点菜单都有可能包含之前所有作为顶点菜单的顶点
  //        //        检验顶点菜单集合是否有被作其上级顶点菜单包含了
  //        Iterator<SysMenuEntity> vertexMenuIterator = vertexMenuSet.iterator();
  //        while (vertexMenuIterator.hasNext()) {
  //          SysMenuEntity vertexMenu = vertexMenuIterator.next();
  //          //          如果剩余菜单已经不存在顶点菜单则已经有其上级顶点菜单包含了需要移除其作为顶点菜单资格
  //          if (!sysMenuEntityList.contains(vertexMenu)) {
  //            vertexMenuIterator.remove();
  //          }
  //        }
  //        //        新顶点菜单
  //        vertexMenuSet.add(menuEntity);
  //      }
  //      //      setParentMenu(menuEntity, sysMenuEntityList);
  //      TreeSet<SysMenuEntity> realVertexMenuSet =
  //          new TreeSet<SysMenuEntity>(
  //              new Comparator<SysMenuEntity>() {
  //                @Override
  //                public int compare(SysMenuEntity o1, SysMenuEntity o2) {
  //                  if (o2.getId().equals(o1.getId())) {
  //                    return 0;
  //                  }
  //                  if (o1.getSort() - o2.getSort() == 0) {
  //                    return 1;
  //                  }
  //                  return o1.getSort() - o2.getSort();
  //                }
  //              });
  //      realVertexMenuSet.addAll(vertexMenuSet);
  //      return realVertexMenuSet;
  //    }
  //    return null;
  //  }

  //
  //  @Override
  //  public  void setChilendMenu(
  //          SysMenuEntity parentMenu, List<SysMenuEntity> sysMenuEntityList) {
  //    TreeSet<SysMenuEntity> childMenuSet = parentMenu.getChildMenus();
  //    if (childMenuSet == null) {
  //      parentMenu.setChildMenus(null);
  //      childMenuSet = parentMenu.getChildMenus();
  //    }
  //    for (SysMenuEntity childenMenu : sysMenuEntityList) {
  //      if (childenMenu.getParentId() != null
  //              && childenMenu.getParentId().equals(parentMenu.getId())) {
  //        childMenuSet.add(childenMenu);
  //      }
  //    }
  //    sysMenuEntityList.remove(parentMenu);
  //    if (childMenuSet.size() == 0) {
  //      return;
  //    }
  //    for (SysMenuEntity childMenu : childMenuSet) {
  //      sysMenuEntityList.remove(childMenu);
  //    }
  //    for (SysMenuEntity nextParentMenu : childMenuSet) {
  //      setChilendMenu(nextParentMenu, sysMenuEntityList);
  //    }
  //  }
}
